#include "prog_menu.h"
#include "mcp2515.h"

uint32_t prog_menu_lastcheck = 0;

uint8_t cursor_min = 0;
uint8_t cursor_max = 0;
uint8_t cursor_pos = 0;

//Function reference to menu printing function.
MenuFunction lcd_current_menu_print;
//Function reference to which handles menu item selection
MenuFunction menu_selection_handler;

uint8_t disp_temperature = 0;

/**
 * can-ctrl
 * Program: mainmenu
 */


int8_t prog_menu_init(void)
{
    register_slot(lcd_button_pressed, btn_event);
	lcd_current_menu_print = lcd_menu_main;
	menu_selection_handler = lcd_menu_main_itemselected;
	lcd_draw_menu(1);
	return 1;
}
int8_t prog_menu_uninit(void)
{
	unregister_slot(lcd_button_pressed, btn_event);
	return 1;
}
int8_t prog_menu_run(void)
{
	if((time() - prog_menu_lastcheck > 100) && disp_temperature)
	{
		lcd_write_temperature(can_message_get_temperature());
		prog_menu_lastcheck = time();
	}
	
	return 1;
}
/**
 * Draws selected menu
 * @param cursor Cursor position
 */
void lcd_draw_menu(int8_t cursor)
{
	lcd_current_menu_print(cursor);
}
//7*21
void lcd_menu_main(int8_t cursor)
{
	cursor_min = 1;
	cursor_max = 3;
    cursor_pos = cursor;
	lcd_clear_display();
	lcd_write_P(0, PSTR("CAN CONTROLLER"));
	lcd_write_P(1, PSTR(" SETTINGS >"));
	lcd_write_P(2, PSTR(" PROGRAM MENU >"));
	lcd_write_P(3, PSTR(" RUNNING PROGRAMS >"));
    lcd_write(cursor, "*");
}

void lcd_menu_main_itemselected(int8_t item)
{
	switch(item)
	{
		case -1: 	
			//Case for user trying to back
			//out from the menu
			//No exit from root menu
			break;
		case 1:
			lcd_current_menu_print = lcd_menu_settings;
			menu_selection_handler = lcd_menu_settings_itemselected;
			lcd_draw_menu(1);
			break;
		case 2:
			lcd_current_menu_print = lcd_menu_program;
			menu_selection_handler = lcd_menu_program_itemselected;
			lcd_draw_menu(1);
			break;
		case 3:
			lcd_current_menu_print = lcd_menu_runningprograms;
			menu_selection_handler = lcd_menu_runningprograms_itemselected;
			lcd_draw_menu(1);
	}
}

void lcd_menu_settings(int8_t cursor)
{
	cursor_min = 1;
	cursor_max = 3;
    lcd_clear_display();
    lcd_write_P(0, PSTR("SETTINGS"));
    lcd_write_P(1, PSTR(" TEMPERATURE DISPLAY"));
	lcd_write_P(2, PSTR(" STARTUP PROGRAMS >"));
	lcd_write_P(3, PSTR(" CALIB POTENTIOMETERS >"));
	
    lcd_write(cursor, "*");
}

void lcd_menu_settings_itemselected(int8_t item)
{
    switch(item)
    {
		case -1:
			lcd_current_menu_print = lcd_menu_main;
			menu_selection_handler = lcd_menu_main_itemselected;
			lcd_draw_menu(1);
			break;
		case 1:
			disp_temperature = disp_temperature ? 0:1;
			if(!disp_temperature)
			{
				lcd_clear_command_line();
				lcd_refresh();
			}
    }
}


void lcd_menu_program(int8_t cursor)
{
	cursor_min = 1;
	cursor_max = 3;
	cursor_pos = cursor;
	
	lcd_clear_display();
	lcd_write_P(0, PSTR("PROGRAM MENU"));
	lcd_write_P(1, PSTR(" MANUAL CONTROL"));
	if(prog_is_running(&prog_manual_control))
		lcd_write_P(1, PSTR(" |"));
	
	lcd_write_P(2, PSTR(" TRIGGER"));
	if(prog_is_running(&prog_trigger))
		lcd_write_P(2, PSTR(" |"));
	
	lcd_write_P(3, PSTR(" IO DEBUG"));
	if(prog_is_running(&prog_io_debug))
		lcd_write_P(3, PSTR(" |"));
	
	lcd_write(cursor, "*");
}

void lcd_menu_program_itemselected(int8_t item)
{
	switch(item)
	{
		case -1:
			lcd_current_menu_print = lcd_menu_main;
			menu_selection_handler = lcd_menu_main_itemselected;
			lcd_draw_menu(1);
			break;
			
		case 1:
			//remove_lcdwriting_progs();
			if(prog_is_running(&prog_manual_control))
				remove_prog(&prog_manual_control);
			else
			{
				remove_lcdwriting_progs();
				add_prog(&prog_manual_control);
			}
			break;

		case 2:
			if(prog_is_running(&prog_trigger))
				remove_prog(&prog_trigger);
			else
				add_prog(&prog_trigger);
			
			lcd_draw_menu(cursor_pos);
			break;
		case 3:
			remove_lcdwriting_progs();
			add_prog(&prog_io_debug);
			break;
	}
}

void lcd_menu_runningprograms(int8_t cursor)
{
	cursor_min = 1;
	cursor_max = 1;
	progs_running();
	lcd_clear_display();
    lcd_write_P(0, PSTR("PROGRAMS"));
	uint8_t i;
	char temp[10];
	for(i=0;i<MAXPROGS && i < 6;i++)
	{
		sprintf(temp, "%i: ", i);
		lcd_write(i+1,temp);

		lcd_write(i+1, _progs[i]->name);
	}
	
}

void lcd_menu_runningprograms_itemselected(int8_t item)
{
    switch(item)
    {
		case -1:
			lcd_current_menu_print = lcd_menu_main;
			menu_selection_handler = lcd_menu_main_itemselected;
			lcd_draw_menu(1);
			break;
    }
}
void lcd_write_temperature(int16_t temperature)
{
    lcd_clear_command_line();
    char temp_line[25];
    sprintf(temp_line, "   %i@C ", temperature);
    lcd_write(6,"");
	lcd_write(7, temp_line);
	
}

void lcd_splash_screen()
{
   char run = 1;
   while(run < 6)
   {
       if(run%2 == 0)
        {
            lcd_clear_display();
            _delay_ms(5);
            lcd_write_P(3, PSTR("    CANNI-HAJOTUS  "));
            lcd_write_P(4, PSTR("         2009      "));
            _delay_ms(5);
            lcd_refresh();
        }
        else if(run %2 == 1)
        {
            lcd_clear_display();
            _delay_ms(5);
            lcd_write_P(2, PSTR("  *****************"));
            lcd_write_P(3, PSTR("  * CANNI-HAJOTUS *"));
            lcd_write_P(4, PSTR("  *      2009     *"));
            lcd_write_P(5, PSTR("  *****************"));
            _delay_ms(5);
            lcd_refresh();

        }
		run++;
		_delay_ms(100);
   }
        //lcd_refresh();
}


/*
typedef struct
{
    Signal sig;
    uint32_t time;
    void *data;
    uint16_t size;
    
}Event;
*/

void lcd_button_pressed(Event *event)
{
    Button *joy = (Button *) event->data;
    
	switch(*joy)
	{
		case joy_up:
			if(cursor_pos> cursor_min)
			{
				lcd_write(cursor_pos-1,"");
				lcd_write(cursor_pos, " ");
				cursor_pos--;
				lcd_write(cursor_pos, "*");
				lcd_write(cursor_pos-1, "");
			}
			break;
		case joy_down:
			if(cursor_pos < cursor_max)
			{
				lcd_write(cursor_pos+1,"");
				lcd_write(cursor_pos, " ");
				cursor_pos++;
				lcd_write(cursor_pos, "*");
				lcd_write(cursor_pos+1, "");
			}
			break;
		case joy_right:
		case joy_enter:
			menu_selection_handler(cursor_pos);
			break;
		case joy_left:
			menu_selection_handler(-1);
			break;
		default:
			break;
	}
	return;
}